package com.soc.course.sercice.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.soc.auth.domain.entity.User;
import com.soc.auth.exception.BusinessException;
import com.soc.auth.mapper.UserMapper;
import com.soc.auth.service.UserService;
import com.soc.course.entity.TaskUser;
import com.soc.course.mapper.TaskUserMapper;
import com.soc.course.sercice.TaskUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.prefs.BackingStoreException;
import java.util.stream.Collectors;

@Service
public class TaskUserServiceImpl extends ServiceImpl<TaskUserMapper, TaskUser> implements TaskUserService {

    @Autowired
    private UserService userService;

    @Autowired
    private TaskUserMapper taskUserMapper;

    /**
     * @Author hjy
     * @Description //TODO 获取用户已经完成了多少个任务点
     * @Date 23:50 2023/6/25
     * @Param courseId: 课程id
     * @Param userId: 用户id
     * @return: java.lang.Integer
     **/
    @Override
    public Integer getUserCourseTask(String courseId, String userId) {
        LambdaQueryWrapper<TaskUser> queryChainWrapper = new LambdaQueryWrapper<>();
        queryChainWrapper.eq(TaskUser::getCourseId, courseId);
        queryChainWrapper.eq(TaskUser::getUserId, userId);
        return Math.toIntExact(count(queryChainWrapper));
    }

    @Override
    public Map<String, Long> getCourseTaskMap(String courseId, String userId) {
        LambdaQueryWrapper<TaskUser> queryChainWrapper = new LambdaQueryWrapper<>();
        queryChainWrapper.eq(TaskUser::getCourseId, courseId);
        queryChainWrapper.eq(TaskUser::getUserId, userId);
        List<TaskUser> taskUsers = taskUserMapper.selectList(queryChainWrapper);
        Map<String, Long> chapterTaskCount = taskUsers.stream()
                .filter(taskPoint -> taskPoint.getUserId().equals(userId) && taskPoint.getCourseId().equals(courseId))
                .filter(taskPoint -> taskPoint.getChapterId() != null)
                .collect(Collectors.groupingBy(TaskUser::getChapterId, Collectors.counting()));


        return chapterTaskCount;
    }

    @Override
    public Map<String, Long> getTaskByClassID(String courseId, String classId) {
        LambdaQueryWrapper<TaskUser> queryChainWrapper = new LambdaQueryWrapper<>();
        queryChainWrapper.eq(TaskUser::getCourseId, courseId);
        queryChainWrapper.eq(TaskUser::getClassId, classId);
        List<TaskUser> taskUsers = taskUserMapper.selectList(queryChainWrapper);
        Map<String, Map<String, Long>> chapterTaskCompletionCount = taskUsers.stream()
                .filter(taskUser -> taskUser.getCourseId().equals(courseId) && taskUser.getClassId().equals(classId))
                .collect(Collectors.groupingBy(TaskUser::getChapterId, Collectors.groupingBy(TaskUser::getTaskId, Collectors.counting()
                        )
                ));
        Map<String, Long> chapterCompletionCount = chapterTaskCompletionCount.entrySet().stream()
                .collect(Collectors.toMap(
                        Map.Entry::getKey,
                        entry -> entry.getValue().values().stream().mapToLong(Long::valueOf).sum()
                ));

        System.out.println(chapterCompletionCount);
        return chapterCompletionCount;
    }

    @Override
    public Map<String, Long> getUserFinshTask(String courseId, String classId) {
        LambdaQueryWrapper<TaskUser> queryChainWrapper = new LambdaQueryWrapper<>();
        queryChainWrapper.eq(TaskUser::getCourseId, courseId);
        queryChainWrapper.eq(TaskUser::getClassId, classId);
        List<TaskUser> taskUsers = taskUserMapper.selectList(queryChainWrapper);

        Map<String, Long> userCompletionCount = taskUsers.stream()
                .filter(taskPoint -> taskPoint.getCourseId().equals(courseId) && taskPoint.getClassId().equals(classId))
                .collect(Collectors.groupingBy(
//                        TaskUser::getUserId,
                        TaskUser::getNo,
                        Collectors.counting()
                ));
        return userCompletionCount;
//        return null;
    }

    /**
     * @Author hjy
     * @Description // 查询对应用户对应的章节,每个人任务点完成情况
     * @Date 0:35 2023/7/6
     * @Param chapterId: 课程id
     * @Param userId: 用户id
     * @return: java.util.Map<java.lang.String, java.lang.Long>
     **/
    @Override
    public Map<String, Boolean> getChapterFinshTask(String chapterId, String userId) {
        LambdaQueryWrapper<TaskUser> queryChainWrapper = new LambdaQueryWrapper<>();
        queryChainWrapper.eq(TaskUser::getUserId, userId);
        queryChainWrapper.eq(TaskUser::getChapterId, chapterId);
        List<TaskUser> taskUsers = taskUserMapper.selectList(queryChainWrapper);
        Map<String, Boolean> taskCompletionMap = taskUsers.stream()
                .collect(Collectors.toMap(TaskUser::getTaskId, taskUser -> true, (existingValue, newValue) -> existingValue));
        return taskCompletionMap;
    }

    @Override
    public boolean updateTaskToComplete(TaskUser taskUser) {

        if (Objects.isNull(taskUser) || StringUtils.isBlank(taskUser.getTaskId()) ){
            throw new BusinessException("任务主键不能为空");
        }
//        if(StringUtils.isBlank(taskUser.getClassId())){
//            throw new NullPointerException("未绑定班级，将不计入成绩，请先绑定班级");
//        }
        LambdaQueryWrapper<User> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userLambdaQueryWrapper.eq(User::getId,taskUser.getUserId());
        User one = userService.getOne(userLambdaQueryWrapper);
        if (Objects.isNull(one)){
            throw new BusinessException("查询不到该用户");
        }
        String no = one.getNo();
        if (StringUtils.isBlank(no)){
            throw new BusinessException("当前未设置学号,将不计入班级成绩");
        }
        taskUser.setNo(no);
        taskUser.setCompleteTime(new Date());
        LambdaQueryWrapper<TaskUser> taskUserLambdaQueryWrapper = new LambdaQueryWrapper<>();
        taskUserLambdaQueryWrapper.eq(TaskUser::getTaskId,taskUser.getTaskId());
        taskUserLambdaQueryWrapper.eq(TaskUser::getNo,taskUser.getNo());
        return this.saveOrUpdate(taskUser,taskUserLambdaQueryWrapper);
    }
}
